﻿using Customer.Core.Data;
using Customer.Model.Interface;
using Customer.Model.Model;
using Common.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using Common.Contract.Authentication.Record;
using Common.Contract.SystemConfig.Record;

namespace Customer.Provider
{
    public class PortfolioProvider : GenericProvider, IPortfolioProvider
    {
        public List<AccountPlanning> RetrieveAccountPlanningByDao(out int totalRecord, UserRecord dao, FilterRecord textSearch = null, string lang = null, int pagesize = 0, int pageindex = 0)
        {

            var data = repository.DbContext as CustomerEntities;
            var query = from x in data.AccountPlannings
                        select x;

            var querySearch = query.Join(data.Branchs, x => x.BranchCodeSme, y => y.BranchCodeSme, (x, y) => new { cust = x, branch = y });
            if (!string.IsNullOrEmpty(textSearch.Region) && textSearch.Region.Trim() != "null")
            {
                querySearch = querySearch.Where(x => textSearch.Region.ToUpper().Contains(x.branch.Region.ToUpper()));
            }
            if (!string.IsNullOrEmpty(textSearch.Branch) && textSearch.Branch.Trim() != "null")
            {
                querySearch = querySearch.Where(x => textSearch.Branch.ToUpper().Contains(x.branch.BranchId.ToUpper()));
            }
            if (!string.IsNullOrEmpty(textSearch.Dao))
            {
                querySearch = querySearch.Where(x => x.cust.DaoCif.Contains(textSearch.Dao));
            }
            if (!string.IsNullOrEmpty(textSearch.DaoName))
            {
                querySearch = querySearch.Where(x => x.cust.DaoName.Contains(textSearch.DaoName));
            }
            if (!string.IsNullOrEmpty(textSearch.Cif))
            {
                querySearch = querySearch.Where(x => x.cust.Cif.Contains(textSearch.Cif));
            }
            if (!string.IsNullOrEmpty(textSearch.CustName))
            {
                querySearch = querySearch.Where(x => x.cust.CustName.Contains(textSearch.CustName));
            }
            if (!string.IsNullOrEmpty(textSearch.Industry))
            {
                query = lang.Equals("vi") ? query.Where(x => x.Industry.Contains(textSearch.Industry)) : query.Where(x => x.Industry.Contains(textSearch.Industry));
            }
            if (!string.IsNullOrEmpty(textSearch.PaymentMethod))
            {
                querySearch = querySearch.Where(x => x.cust.PaymentMethod.Contains(textSearch.PaymentMethod));
            }
            if (!string.IsNullOrEmpty(textSearch.StatusAccPlan))
            {
                switch (textSearch.StatusAccPlan)
                {
                    case "0":
                        querySearch = querySearch.Where(x => x.cust.Status == 0);
                        break;
                    case "1":
                        querySearch = querySearch.Where(x => x.cust.Status == 1);
                        break;
                    default:
                        break;
                }
            }
            query = querySearch.OrderBy(x => new { x.branch.Region, x.branch.BranchId, x.cust.DaoCif }).Select(x => x.cust);
            totalRecord = query.Count();
            if (pagesize > 0 && pageindex >= 0)
            {
                query = query.Skip(pageindex * pagesize).Take(pagesize);
            }
            return query.ToList();
        }
        public List<AccountPlanning> RetrieveAccountPlanningByCif(string cif)
        {
            var data = repository.DbContext as CustomerEntities;
            var query = from x in data.AccountPlannings
                        where x.Cif == cif
                        select x;
            return query.ToList();
        }
        public List<AccountPlanningFinance> RetrieveAccountPlanningFinanceByCif(string cif)
        {
            var data = repository.DbContext as CustomerEntities;
            var query = from x in data.AccountPlanningFinances
                        where x.Cif == cif && (x.Status == 0 || x.Status == 1)
                        select x;
            query = query.OrderBy(x => new { x.OrderNum, x.Name });
            return query.ToList();
        }
        public List<AccountPlanningFinanceResult> RetrieveAccountPlanningFinanceResultByCif(string cif)
        {
            var data = repository.DbContext as CustomerEntities;
            var query = from x in data.AccountPlanningFinanceResults
                        where x.Cif == cif && (x.Status == 0 || x.Status == 1)
                        select x;
            query = query.OrderBy(x => new { x.OrderNum, x.Name });
            return query.ToList();
        }
        public List<AccountPlanningProductHolding> RetrieveAccountPlanningProductHoldingByCif(string cif)
        {
            var data = repository.DbContext as CustomerEntities;
            var query = from x in data.AccountPlanningProductHoldings
                        where x.Cif == cif && (x.Status == 0 || x.Status == 1)
                        select x;
            query = query.OrderBy(x => x.OrderNum);
            return query.ToList();
        }
        public List<AccountPlanningProductHoldingResult> RetrieveAccountPlanningProductHoldingResultByCif(string cif)
        {
            var data = repository.DbContext as CustomerEntities;
            var query = from x in data.AccountPlanningProductHoldingResults
                        where x.Cif == cif && (x.Status == 0 || x.Status == 1)
                        select x;
            query = query.OrderBy(x => x.OrderNum);
            return query.ToList();
        }
        public AccountPlanning Retrieve(string cif)
        {
            cif = (cif ?? string.Empty).ToUpper();
            return repository.FindOne<AccountPlanning>(x => x.Cif.ToUpper() == cif);
        }
        public bool UpdateAccountPlanning(AccountPlanning dataUpdate)
        {
            try
            {
                var dataChecked = Retrieve(dataUpdate.Cif);
                if (dataChecked == null) return false;
                if (dataUpdate.ActionPlanT62016.IsNullOrWhiteSpace()) dataChecked.ActionPlanT62016 = dataUpdate.ActionPlanT62016;
                dataChecked.MainSector = dataUpdate.MainSector;
                dataChecked.PaymentMethod = dataUpdate.PaymentMethod;
                dataChecked.WalletShare = dataUpdate.WalletShare;
                dataChecked.SpBanCheo = dataUpdate.SpBanCheo;
                dataChecked.VuongMac = dataUpdate.VuongMac;
                dataChecked.KhHoTro = dataUpdate.KhHoTro;

                repository.UnitOfWork.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }
        public IEnumerable<AccountPlanningFinance> RetrieveAcountPlanningFinance(string cif)
        {
            cif = (cif ?? string.Empty).ToUpper();
            return repository.Find<AccountPlanningFinance>(x => x.Cif.ToUpper() == cif);
        }

        public IEnumerable<AccountPlanningProductHolding> RetrieveAcountPlanningProductHolding(string cif)
        {
            cif = (cif ?? string.Empty).ToUpper();
            return repository.Find<AccountPlanningProductHolding>(x => x.Cif.ToUpper() == cif);
        }
        public bool UpdateAccountPlanningFinance(Dictionary<string, AccountPlanningFinance> dataUpdate, string cif)
        {
            try
            {
                var dataChecked = RetrieveAcountPlanningFinance(cif);
                if (dataChecked == null || dataChecked.Count() == 0) return false;
                dataChecked.ToList().ForEach(x =>
                {
                    x.Year = dataUpdate[x.OrderNum.ToString()].Year;
                    x.Month1 = dataUpdate[x.OrderNum.ToString()].Month1;
                    x.Month2 = dataUpdate[x.OrderNum.ToString()].Month2;
                    x.Month3 = dataUpdate[x.OrderNum.ToString()].Month3;
                    x.Month4 = dataUpdate[x.OrderNum.ToString()].Month4;
                    x.Month5 = dataUpdate[x.OrderNum.ToString()].Month5;
                    x.Month6 = dataUpdate[x.OrderNum.ToString()].Month6;
                    x.Month7 = dataUpdate[x.OrderNum.ToString()].Month7;
                    x.Month8 = dataUpdate[x.OrderNum.ToString()].Month8;
                    x.Month9 = dataUpdate[x.OrderNum.ToString()].Month9;
                    x.Month10 = dataUpdate[x.OrderNum.ToString()].Month10;
                    x.Month11 = dataUpdate[x.OrderNum.ToString()].Month11;
                    x.Month12 = dataUpdate[x.OrderNum.ToString()].Month12;
                    x.Status = 1;
                    x.ChangeDate = DateTime.Now;
                    x.CreatedDate = x.CreatedDate.HasValue ? x.CreatedDate.Value : DateTime.Now;
                });
                repository.UnitOfWork.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }

        public bool UpdateAccountPlanningProductHolding(Dictionary<string, AccountPlanningProductHolding> dataUpdate, string cif)
        {
            try
            {
                var dataChecked = RetrieveAcountPlanningProductHolding(cif);
                if (dataChecked == null || dataChecked.Count() == 0) return false;
                dataChecked.ToList().ForEach(x =>
                {
                    x.Year = dataUpdate[x.OrderNum.ToString()].Year;
                    x.Month1 = dataUpdate[x.OrderNum.ToString()].Month1;
                    x.Month2 = dataUpdate[x.OrderNum.ToString()].Month2;
                    x.Month3 = dataUpdate[x.OrderNum.ToString()].Month3;
                    x.Month4 = dataUpdate[x.OrderNum.ToString()].Month4;
                    x.Month5 = dataUpdate[x.OrderNum.ToString()].Month5;
                    x.Month6 = dataUpdate[x.OrderNum.ToString()].Month6;
                    x.Month7 = dataUpdate[x.OrderNum.ToString()].Month7;
                    x.Month8 = dataUpdate[x.OrderNum.ToString()].Month8;
                    x.Month9 = dataUpdate[x.OrderNum.ToString()].Month9;
                    x.Month10 = dataUpdate[x.OrderNum.ToString()].Month10;
                    x.Month11 = dataUpdate[x.OrderNum.ToString()].Month11;
                    x.Month12 = dataUpdate[x.OrderNum.ToString()].Month12;
                    x.Status = 1;
                    x.ChangeDate = DateTime.Now;
                    x.CreatedDate = x.CreatedDate.HasValue ? x.CreatedDate.Value : DateTime.Now;
                });
                repository.UnitOfWork.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }

        public AccountPlanningHistory RetrieveLastChangeByCif(string cif, int type)
        {
            var data = repository.DbContext as CustomerEntities;
            var query = from x in data.AccountPlanningHistorys
                        where x.Cif == cif && x.Type == type
                        select x;
            query = query.OrderByDescending(x => x.ChangeDate);
            return query.FirstOrDefault();
        }

        public List<AccountPlanningHistory> RetrieveAccountPlanningHistoryByCif(string cif)
        {
            var data = repository.DbContext as CustomerEntities;
            var query = from x in data.AccountPlanningHistorys
                        where x.Cif == cif
                        select x;
            return query.ToList();
        }

        public List<AccountPlanningHistory> RetrieveAccountPlanningHistoryByTypeCif(string cif, string type)
        {
            int typeNum = int.Parse(type);
            var data = repository.DbContext as CustomerEntities;
            var query = from x in data.AccountPlanningHistorys
                        where x.Cif == cif && x.Type == typeNum
                        select x;
            return query.ToList();
        }

        public bool SaveAccountPlanningHistory(AccountPlanningHistory obj)
        {
            try
            {
                repository.AccountPlanningHistorys.Add(obj);
                repository.UnitOfWork.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}